package com.jysz.certificate.web.action.report;

import java.awt.Font;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.jfree.chart.ChartColor;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardPieSectionLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer3D;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.ui.TextAnchor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.jysz.certificate.action.AbstractBaseAction;
import com.jysz.certificate.service.cm.CertificationService;
import com.jysz.certificate.service.mf.BillOptionService;
import com.jysz.certificate.utils.DateUtil;

/**
 * 图形报表
 * 
 * @author xuxiaolong
 * 
 */
@Controller
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Namespace("/report/grap")
public class GraphicAction extends AbstractBaseAction {

	private static final long serialVersionUID = 1L;
	private static final Logger LOG = LoggerFactory
			.getLogger(GraphicAction.class);

	@Resource
	private BillOptionService optionService;
	@Resource
	private CertificationService cfService;
	private JFreeChart chart;
	private Integer year;
	private Integer endYear=Integer.parseInt(DateUtil.formatDate(new Date(),"yyyy"));
	private Date startDate;
	private Date endDate;

	// 年度总收入-按月份统计
	@Action("incomeTotal")
	public String incomeTotal() {
		if (year != null) {
			Map<Integer, Double> rus = optionService.findIncomeTotal(year);
			DefaultCategoryDataset dataset = new DefaultCategoryDataset();
			for (Object i : rus.keySet()) {
				dataset.addValue(rus.get(i), i.toString() + "月", i.toString()
						+ "月");
			}

			chart = ChartFactory.createBarChart3D("", "月份", "金额(万元)", dataset,
					PlotOrientation.VERTICAL, true, false, false);
			chart.setTitle(new TextTitle(year + "年度总收入", new Font("黑体",
					Font.ITALIC, 22)));

			setZhuFont();// 设置样式
			return showData();
		}
		return "income_total";
	}

	// 年度总收入-按金融机构统计
	@Action("incomeFin")
	public String incomeFin() {

		if (year != null) {

			Map<String, Double> rus = optionService.findIncomeFin(year);
			DefaultPieDataset dataset = new DefaultPieDataset();
			for (String key : rus.keySet()) {
				dataset.setValue(key, rus.get(key));
			}

			chart = ChartFactory.createPieChart(year + "年各合作金融机构收入份额占比",
					dataset, true, false, false);
			setBinFont();// 设置样式
			return showData();
		}
		return "income_fin";
	}

	// 按金融机构统计签约店铺
	@Action("finShop")
	public String finShop() {
		
		if (startDate != null && endDate != null) {
			LinkedHashMap<String, Integer> rus = optionService.findFinShop(startDate,endDate);
			DefaultCategoryDataset dataset = new DefaultCategoryDataset();
			
			for (Object i : rus.keySet()) {
				dataset.addValue(rus.get(i), i.toString(), i.toString());
			}
			chart = ChartFactory.createBarChart3D("", "金融机构", "店数量", dataset,
					PlotOrientation.VERTICAL, true, false, false);
			chart.setTitle(new TextTitle("各合作金融机构展业店数量分析", new Font("黑体",
					Font.ITALIC, 22)));
			//-------设置展业店数量最小单位为1
			if(rus!=null){
				int max=0;
				for(Integer i:rus.values()){
					if(i>max){
						max=i;
					}
				}
				CategoryPlot plot = (CategoryPlot) chart.getPlot();
				NumberAxis numberAxis = (NumberAxis) plot.getRangeAxis();
				NumberFormat nf=NumberFormat.getIntegerInstance();
				numberAxis.setNumberFormatOverride(nf);
				if(max<=10){
					numberAxis.setTickUnit(new NumberTickUnit(1D));
				}else{
					numberAxis.setAutoTickUnitSelection(true);//数据轴的数据标签是否自动确定
				}
			}
			//-------
			setZhuFont();// 设置样式
			return showData();
		}

		return "fin_shop";
	}

	// 融资车 -按选定年度范围
	@Action("carTotal")
	public String carTotal() {

		if (year != null && endYear != null) {
			startDate=DateUtil.parseDate(year+"-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss");
			endDate=DateUtil.parseDate(endYear+"-12-31 23:59:59", "yyyy-MM-dd HH:mm:ss");
			Map<Integer, Integer> rus= cfService.findCarTotal(startDate, endDate);
			DefaultCategoryDataset dataset = new DefaultCategoryDataset();
			for (Object i : rus.keySet()) {
				dataset.addValue(rus.get(i), i.toString()+"年", i.toString()+"年");
			}
			chart = ChartFactory.createBarChart3D("", "年份", "车数量", dataset,
					PlotOrientation.VERTICAL, true, false, false);
			chart.setTitle(new TextTitle("融资车总台数合计同比", new Font("黑体",
					Font.ITALIC, 22)));

			setZhuFont();// 设置样式
			return showData();
		}
		return "car_total";
	}

	// 按金融机构统计
	@Action("carFin")
	public String carFin() {
		
		if (year != null && endYear != null) {
			startDate=DateUtil.parseDate(year+"-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss");
			endDate=DateUtil.parseDate(endYear+"-12-31 23:59:59", "yyyy-MM-dd HH:mm:ss");
			List<Object[]>  rus = cfService.findCarFin(startDate, endDate);
			DefaultCategoryDataset dataset = new DefaultCategoryDataset();
			for (Object ary[] : rus) {
				if(ary.length==3)
					dataset.addValue(Integer.parseInt(ary[2].toString()),ary[0]+"年",ary[1].toString());
			}
			chart = ChartFactory.createBarChart3D("", "", "车数量", dataset,
					PlotOrientation.VERTICAL, true, false, false);
			chart.setTitle(new TextTitle(year+"年-"+endYear+"年各银行融资车台数", new Font("黑体",
					Font.ITALIC, 22)));

			setZhuFont();// 设置样式
			return showData();
		}
		return "car_fin";
	}

	// 统计年度融资车
	@Action("carYear")
	public String carYear() {
		
		if (year != null) {
			startDate=DateUtil.parseDate(year+"-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss");
			endDate=DateUtil.parseDate(year+"-12-31 23:59:59", "yyyy-MM-dd HH:mm:ss");
			Map<String, Integer> rus = cfService.findCarYear(startDate, endDate);
			DefaultPieDataset dataset = new DefaultPieDataset();
			for (String key : rus.keySet()) {
				dataset.setValue(key, rus.get(key));
			}

			chart = ChartFactory.createPieChart(year + "年各银行融资车台数分布",
					dataset, true, false, false);
			setBinFont();// 设置样式
			return showData();
		}
		return "car_year";
	}

	//柱状图样式
	private void setZhuFont() {

		// 设置总的背景颜色
		chart.setBackgroundPaint(ChartColor.WHITE);

		// 修改图例的字体
		LegendTitle legend = chart.getLegend();
		legend.setItemFont(new Font("宋体", Font.ITALIC, 14));
		CategoryPlot plot = (CategoryPlot) chart.getPlot();

		// 设置图的背景颜色
		plot.setBackgroundPaint(ChartColor.WHITE);
		// 设置表格线颜色
		plot.setRangeGridlinePaint(ChartColor.gray);

		// 取得横轴
		CategoryAxis categoryAxis = plot.getDomainAxis();
		categoryAxis.setLabelFont(new Font("宋体", Font.BOLD, 22));

		// 分类标签以45度角倾斜
		categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
		categoryAxis.setTickLabelFont(new Font("宋体", Font.BOLD, 15));

		// 取得纵轴
		NumberAxis numberAxis = (NumberAxis) plot.getRangeAxis();
		numberAxis.setLabelFont(new Font("宋体", Font.BOLD, 22));
		
		BarRenderer3D renderer = (BarRenderer3D) plot.getRenderer();
		renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());// 显示每个柱的数值
		renderer.setBaseItemLabelsVisible(true);
		// 数字显示
		renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(
				ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER));
		renderer.setItemLabelAnchorOffset(8D);// 设置柱形图上的文字偏离值
		renderer.setSeriesItemLabelsVisible(0, true);
//		renderer.setSeriesItemLabelFont(4, new Font("黑体", Font.BOLD, 14));

		// 柱子的宽度
		renderer.setMaximumBarWidth(0.04);
		renderer.setItemMargin(0.000000005);
		plot.setRenderer(renderer);
	}

	// 饼状图样式
	private void setBinFont() {

		chart.getTitle().setFont(new Font("黑体", Font.BOLD, 25));// 设置标题字体
		PiePlot pp = (PiePlot) chart.getPlot();
		pp.setLabelFont(new Font("黑体", Font.BOLD, 13));
		chart.getLegend().setItemFont(new Font("黑体", Font.BOLD, 13));
//		pp.setLabelGenerator(new StandardPieSectionLabelGenerator("{0} = {2}"));
		pp.setNoDataMessage("无数据可供显示！"); // 没有数据的时候显示的内容 
		pp.setLabelGenerator(new StandardPieSectionLabelGenerator( 
		("{0}{2}"), NumberFormat.getNumberInstance(), 
		new DecimalFormat("0.0%"))); 


	}

	// 将报表输出到页面
	private String showData() {
		ServletOutputStream out = null;
		HttpServletResponse response = getResponse();
		try {
			out = response.getOutputStream();
			ChartUtilities.writeChartAsJPEG(out, 1f, chart, 500, 400, null);
		} catch (IOException e) {
			LOG.error("图形报表异常：" + e.getMessage());
		}
		return null;
	}

	public JFreeChart getChart() {
		return chart;
	}

	public void setChart(JFreeChart chart) {
		this.chart = chart;
	}

	public Integer getYear() {
		return year;
	}

	public void setYear(Integer year) {
		this.year = year;
	}

	public Date getStartDate() {
		return startDate;
	}

	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	public Date getEndDate() {
		return endDate;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	public Integer getEndYear() {
		return endYear;
	}

	public void setEndYear(Integer endYear) {
		this.endYear = endYear;
	}

	public CertificationService getCfService() {
		return cfService;
	}

	public void setCfService(CertificationService cfService) {
		this.cfService = cfService;
	}

}
